import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as stats

plt.style.use('ggplot')

import plotly.express as px
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
import plotly.figure_factory as ff
from plotly import subplots
from plotly.subplots import make_subplots
from datetime import datetime, date, timedelta
# import prophet
import warnings
warnings.filterwarnings('ignore')
pd.set_option('display.max_columns', 100)
pd.set_option('display.max_rows', 100)
import os
API_ENDPOINT = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
# API接受日期参数来过滤数据
def fetch_covid_data(start_date, end_date):
    params = {
        'start_date': start_date.strftime('%Y-%m-%d'),
        'end_date': end_date.strftime('%Y-%m-%d')
    }
    response = requests.get(API_ENDPOINT, params=params)
    if response.status_code == 200:
        # API返回的是JSON格式的数据
        data = response.json()
        df = pd.DataFrame(data['results'])
        return data
    else:
        print(f"Error fetching data: {response.status_code}")
        return None
    # 设置日期范围
start_date = datetime.datetime(2020, 1, 1)
end_date = datetime.datetime(2020, 3, 31)
# 获取数据
covid_data = fetch_covid_data(start_date, end_date)
# 保存为CSV文件
covid_data.to_csv('D:\大三下\机器学习\covid_19_data.csv\covid_19_data.csv', index=False)
# 只是打印数据（因为covid_data可能是一个复杂的JSON对象或字典）
print(covid_data)
df=pd.read_csv('D:\大三下\机器学习\covid_19_data.csv\covid_19_data.csv.csv')
df.set_index('ObservationDate',inplace=True)
# df=df[(df['ObservationDate'] >= '2020/01/22') & (df['ObservationDate'] <= '2020/03/31')]
df=df['01/22/2020':'03/31/2020']
# 显示前5行
pd.set_option('display.max_columns', None)
print(df.iloc[:,:7])

# 显示Province/State为空的行
print(df[df['Province/State'].isnull()])
countries = df_groupByCountry.Country.unique().tolist()
df_plot = df.loc[df.count.isin(countries[:10]), ['ObservationDate', 'Country/Region', 'Confirmed']].groupby(['ObservationDate', 'Country/Region']).max().reset_index()

from pandas.core.frame import DataFrame
fig=px.scatter(DataFrame(date),x="Date", y="ConfirmedCases", color='Province_State')
fig.show()
fig = px.line(df, x="ObservationDate", y="Confirmed", color='Province/State')
fig.update_layout(title=' Confirmed Cases per Day for  Countries',
                   xaxis_title='Date',
                   yaxis_title='No.of Confirmed Cases')
fig.show()
plt.scatter(date2['ForecastId'],date2['ConfirmedCases'],label='forecast Data')
# date['ConfirmedCases1']=date['ConfirmedCases1'].astype("Int64")
plt.plot(date['ForecastId'],list(date['ConfirmedCases']),color='b',label='acture Data')
plt.legend()
plt.show()
# 创建每个国家的确认病例柱状图
fig = px.bar(df, y='Confirmed', hover_data=['Province/State', 'Deaths', 'Recovered'], color='Province/State')
annotations = [dict(xref='paper', yref='paper', x=0.0, y=1.05,
                    xanchor='left', yanchor='bottom',
                    text='Confirmed bar plot for each country',
                    font=dict(family='Arial',
                              size=30,
                              color='rgb(37,37,37)'),
                    showarrow=False)]
fig.update_layout(annotations=annotations)
fig.show()
# 创建每个国家的死亡病例柱状图
fig = px.bar(df,  y='Deaths', hover_data=['Province/State', 'Confirmed', 'Recovered'], color='Country/Region')
annotations = [dict(xref='paper', yref='paper', x=0.0, y=1.05,
                    xanchor='left', yanchor='bottom',
                    text='Deaths bar plot for each country',
                    font=dict(family='Arial',
                              size=30,
                              color='rgb(37,37,37)'),
                    showarrow=False)]
fig.update_layout(annotations=annotations)
fig.show()

# 创建每个国家的康复病例柱状图
fig = px.bar(df,  y='Recovered', hover_data=['Province/State', 'Confirmed', 'Deaths'], color='Country/Region')
annotations = [dict(xref='paper', yref='paper', x=0.0, y=1.05,
                    xanchor='left', yanchor='bottom',
                    text='Recovered bar plot for each country',
                    font=dict(family='Arial',
                              size=30,
                              color='rgb(37,37,37)'),
                    showarrow=False)]
fig.update_layout(annotations=annotations)
fig.show()
# 创建中国大陆的确诊病例柱状图（注意：这里我们使用'Country'列来筛选，因为通常'Country'会包含'China'或'Mainland China'）
china_data = df[df['Country/Region'] == 'Mainland China']  # 假设'Country/Region'是列名
fig = px.bar(df,  y='Confirmed', hover_data=['Province/State', 'Deaths', 'Recovered'],
             color='Province/State')
annotations = [dict(xref='paper', yref='paper', x=0.0, y=1.05,
                    xanchor='left', yanchor='bottom',
                    text='Confirmed bar plot for Mainland China',
                    font=dict(family='Arial',
                              size=30,
                              color='rgb(37,37,37)'),
                    showarrow=False)]
fig.update_layout(annotations=annotations)
fig.show()
data = pd.read_csv('D:\大三下\机器学习\covid_19_data.csv\covid_19_data.csv')
# 按日期对数据进行汇总
summarized_data = data.groupby('ObservationDate').agg({
    'Confirmed': 'sum',
    'Deaths': 'sum',
    'Recovered': 'sum'
}).reset_index()

# 索引确诊人数数据
confirmed_cases = summarized_data['Confirmed'].values
t = np.arange(len(confirmed_cases))

# 定义 C-SEIR 模型
def cseir_model(y, t, beta, sigma, gamma, mu, nu):
    S, E, I, R = y
    N = S + E + I + R
    dSdt = mu - beta * S * I / N - mu * S
    dEdt = beta * S * I / N - (sigma + mu) * E
    dIdt = sigma * E - (gamma + nu + mu) * I
    dRdt = gamma * I - mu * R
    return dSdt, dEdt, dIdt, dRdt

# 定义损失函数
def loss_function(params, y0):
    beta, sigma, gamma, mu, nu = params
    y = odeint(cseir_model, y0, t, args=(beta, sigma, gamma, mu, nu))
    y_pred = y[:, 2]  # 预测的感染人数
    return np.sum((y_pred - confirmed_cases) ** 2)

# 初始状态
S0 = 10000000  # 假设初始总人口数
E0 = 1000      # 初始暴露人数
I0 = 100       # 初始感染人数
R0 = 0         # 初始康复人数
y0 = [S0, E0, I0, R0]  # 初始状态向量

# 使用最小二乘法拟合模型
initial_guess = [0.2, 0.1, 0.05, 0.01, 0.005]  # 初始参数猜测值
result = minimize(loss_function, initial_guess, args=(y0,), method='Nelder-Mead')

# 打印最优参数
print("Optimal parameters:", result.x)
# 绘制拟合曲线
y = odeint(cseir_model, y0, t, args=tuple(result.x))
plt.plot(t, confirmed_cases, 'ro', label='Reported cases')
plt.plot(t, y[:, 2], label='SEIR model prediction')
plt.xlabel('Time')
plt.ylabel('Confirmed cases')
plt.legend()
plt.show()
y[:, 2].to_csv('submission.csv', index=False)